package subraSoft.centaurus.gui.option.amb;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import subraSoft.centaurus.model.cobj.CenDefaultCObj;
import subraSoft.centaurus.model.service.CenIPaginableService;

public abstract class CenPaginableTableModel extends AbstractTableModel
{
	private static final long serialVersionUID = 1L;
	
	private List<CenDefaultCObj> pageDataProvider;
	private int pageSize;
	private int currentPage = 0;

	private CenIPaginableService service;
	
	/**
	 * Constructor.
	 */
	public CenPaginableTableModel(int pageSize, CenIPaginableService service)
	{
		this.pageSize = pageSize;
		this.service = service;
		fillCurrentPage();
	}

	private void fillCurrentPage() 
	{
		pageDataProvider = service.getList(currentPage*pageSize, pageSize);
	}

	public int getRowCount() 
	{
		return pageDataProvider.size();
	}
	
	/**
	 * Borra el elemento de la tabla (no relaiza el borrado en el modelo).
	 * 
	 * @param rowToDelete indice de el elemento a borrar.
	 */
	public void deleteRow(int rowToDelete)
	{
		service.delete(getObject(rowToDelete));
		pageDataProvider.remove(rowToDelete);
		fireTableRowsDeleted(rowToDelete,rowToDelete);
	}
	
	/**
	 * Borra el elemento de la tabla (no relaiza el insert en el modelo).
	 * 
	 * @param element elemento a agregar en la tabla.
	 */
	public void addRow(CenDefaultCObj element)
	{
		Object id = service.saveOrUpdate(element);
		element.setId(id);
		pageDataProvider.add(0, element);
		fireTableRowsInserted(0,0);
	}
	
	/**
	 * Obtiene el objeto del indice pasado como parametro.
	 * 
	 * @param index indice del elemento requerido
	 * @return el elemento en el indice dado
	 */
	public CenDefaultCObj getObject(int index)
	{
		return pageDataProvider.get(index);
	}
	
	/**
	 * Actualiza el elemento en la tabla (todos sus campos).
	 * 
	 * @param elemento intercambia el elemento del inicide pasado por este nuevo elemento.
	 * @param row indice de la fila a actualizar.
	 */
	public void updateRow(CenDefaultCObj elemento, int row)
	{
		service.saveOrUpdate(elemento);
		pageDataProvider.remove(row);
		pageDataProvider.add(row, elemento);
		fireTableRowsUpdated(row,row);
	}	
	
	public void toPage(int index)
	{
		currentPage = index;
		fillCurrentPage();
		fireTableDataChanged();
	}
	
	public void nextPage()
	{
		if (hasNext())
		{
			currentPage++;
			toPage(currentPage);
		}
	}
	
	public void backPage()
	{
		if (hasBack()) 
		{
			currentPage--;
			toPage(currentPage);
		}
	}
	
	public int getPageCount()
	{
		return (int) Math.ceil( (double)service.getSize() / pageSize );
	}
	
	public boolean hasNext()
	{
		return currentPage < getPageCount() - 1;
	}
	
	public boolean hasBack()
	{
		return currentPage > 0;
	}
	
	/**
	 * Ojo paginas comenzando desde 1, no como se usa internamente.
	 * 
	 * @return
	 */
	public int getCurrentPage() 
	{
		return currentPage+1;
	}
	
}
